Make SensorReadings a timescaledb table - #4463
Conversation
|
PR titles are automatically included in the changelog:
|
|
I think there's a better (magic) process we have to use for timescale tables, I'll add more details soon once I have time to go through this process |
Bring the branch up to date with develop (deps moved to pyproject/uv, Django 6, Postgres 18 timescaledb-ha image) and make SensorReading an actual TimescaleDB hypertable: - Resolve sensors.py conflict; develop already fixed Sensor.unique_together (migration 0216), so keep only the SensorReading.timestamp -> TimescaleDateTimeField change here. - Add django-timescaledb dependency (pyproject.toml + uv.lock); drop the obsolete requirements/base.txt edit (develop removed that file). - Switch DB ENGINE to a SEED timescale/postgis backend across settings so the hypertable is created during migration. The backend subclasses django-timescaledb's postgis wrapper and fixes an upstream NameError in the released 0.2.13 (schema.py references settings without importing it), which otherwise breaks migrating an existing table into a hypertable. - Reorder the timescale migration to the end of the graph: delete the old 0215_auto_20240105_1306 (conflicted with develop's 0215) and recreate it as 0255_alter_sensorreading_timestamp depending on 0254_repair_missing_primary_keys. Verified: makemigrations --check clean, full migrate creates the seed_sensorreading hypertable, and seed/tests/test_sensors passes (15/15). Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
This PR implements TimescaleDB support for SensorReading by introducing django-timescaledb, switching SensorReading.timestamp to a Timescale-aware field, and updating Django’s DB engine configuration so migrations can convert the existing table into a hypertable (with a local backend workaround for an upstream bug in django-timescaledb==0.2.13).
Changes:
- Add
django-timescaledb==0.2.13and useTimescaleDateTimeFieldforSensorReading.timestamp(with a migration to alter the existing column). - Introduce a custom Timescale+PostGIS backend wrapper (
seed.backends.timescale_postgis) to work around an upstream schema editor bug during hypertable creation. - Update dev/docker/test settings to use the new Timescale backend (and configure
TIMESCALE_DB_BACKEND_BASEfor parallel test DB cloning).
Reviewed changes
Copilot reviewed 11 out of 12 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
uv.lock |
Locks django-timescaledb dependency for reproducible installs. |
pyproject.toml |
Adds django-timescaledb==0.2.13 to runtime dependencies. |
seed/models/sensors.py |
Switches SensorReading.timestamp to TimescaleDateTimeField to enable hypertable creation behavior. |
seed/migrations/0255_alter_sensorreading_timestamp.py |
Alters the existing timestamp column to the Timescale field type to trigger hypertable conversion. |
seed/backends/timescale_postgis/base.py |
Adds a backend wrapper/schema editor override to avoid an upstream NameError during hypertable migration. |
seed/backends/timescale_postgis/__init__.py |
Declares the new backend package. |
config/settings/test.py |
Uses the Timescale backend in tests while preserving parallel DB cloning behavior via TIMESCALE_DB_BACKEND_BASE. |
config/settings/docker_test.py |
Same as above for dockerized test runs. |
config/settings/test_local_untracked.py |
Switches local test settings to use the Timescale backend. |
config/settings/docker.py |
Switches docker runtime DB engine to the Timescale backend. |
config/settings/docker_dev.py |
Switches docker dev DB engine to the Timescale backend. |
config/settings/dev.py |
Switches local dev DB engine to the Timescale backend. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| if should_migrate and getattr(settings, "TIMESCALE_MIGRATE_HYPERTABLE_WITH_FRESH_TABLE", False): | ||
| raise NotImplementedError() |
| class SensorReading(models.Model): | ||
| reading = models.FloatField(null=True) | ||
| timestamp = models.DateTimeField() | ||
| timestamp = TimescaleDateTimeField(interval="7 days") |
#4252